package com.lmabbe.common.datasources.handle;

import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import com.baomidou.dynamic.datasource.creator.HikariDataSourceCreator;
import com.baomidou.dynamic.datasource.ds.GroupDataSource;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty;
import com.baomidou.dynamic.datasource.strategy.LoadBalanceDynamicDataSourceStrategy;
import com.baomidou.dynamic.datasource.support.DdConstants;
import com.lmabbe.common.datasources.converter.DatabaseConverter;
import com.lmabbe.common.global.context.TenantBuildContext;
import com.lmabbe.common.global.context.metadata.tenant.Database;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;

import javax.sql.DataSource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 添加来自平台管理的数据库链接
 * @author lmabbe
 */
@Slf4j
public class InitConnectPoolHandler extends InitApplicationHandle{

    public InitConnectPoolHandler(ApplicationContext applicationContext, TenantBuildContext tenantContext) {
        super(applicationContext, tenantContext);
    }

    @Override
    void handle(InitApplicationContext context) {
        log.info(">>>>>>>>>添加来自平台管理的数据库链接>>>>>>>");
        List<String> connectionPoolNames = new ArrayList<>();
        for (Database database : tenantContext.getTenantDatabases()) {
            DataSourceProperty dataSourceProperty = DatabaseConverter.INSTANCE.converter2Property(database);
            String connectionPoolName = addConnectionPool(tenantContext.getTenantId(), database.getDsType(), dataSourceProperty);
            connectionPoolNames.add(connectionPoolName);
        }
        context.setDatabaseIds(connectionPoolNames);
    }

    /**
     * 添加数据源连接池
     *
     * @param tenantId : 租户ID
     * @param dsType   : 数据源类型
     * @param property : 链接参数
     * @return {@link String}
     * @date 2021/12/25 6:06 PM
     * @author liming
     */
    public String addConnectionPool(Long tenantId, Integer dsType, DataSourceProperty property) {
        DynamicRoutingDataSource dynamicRoutingDataSource = (DynamicRoutingDataSource) applicationContext.getBean(DataSource.class);
        Map<String, GroupDataSource> currentGroupDataSources = dynamicRoutingDataSource.getCurrentGroupDataSources();
        GroupDataSource groupDataSource = currentGroupDataSources.get(String.valueOf(tenantId));
        String ds;
        for (int i = 1; true; i++) {
            ds = tenantId + "_" + (dsType == 2 ? DdConstants.SLAVE : DdConstants.MASTER) + "_" + i;
            if (groupDataSource == null || (!groupDataSource.getDataSourceMap().containsKey(ds))) {
                break;
            }
        }
        dynamicRoutingDataSource.setStrategy(LoadBalanceDynamicDataSourceStrategy.class);
        HikariDataSourceCreator creator = applicationContext.getBean(HikariDataSourceCreator.class);
        DataSource dataSource = creator.createDataSource(property);
        dynamicRoutingDataSource.addDataSource(ds, dataSource);
        return ds;
    }
}
